package com.wmada.toolkit.rest.builder;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.entity.ContentType;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.HeaderGroup;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author will.ma
 * @date 2019-4-25
 */
@SuppressWarnings("unused")
public class HeaderBuilder {

    private static final Base64 BASE_64 = new Base64();

    public static final String UA_CHROME  = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36";
    public static final String UA_FIREFOX = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0";
    public static final String UA_MOBILE  = "Mozilla/5.0 (Linux; Android 9; G8142 Build/47.2.A.10.28) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3117.2 Mobile Safari/537.36";
    public static final String UA_WECHAT  = "Mozilla/5.0 (Linux; Android 9; G8142 Build/47.2.A.10.28; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/6.2 TBS/044607 Mobile Safari/537.36 MMWEBID/921 MicroMessenger/7.0.4.1420(0x27000437) Process/tools NetType/4G Language/zh_CN";
    public static final String UA_IPHONE  = "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1";

    private final HeaderGroup headers = new HeaderGroup();

    private HeaderBuilder() {
    }

    public static HeaderBuilder create() {
        return new HeaderBuilder();
    }

    public static HeaderBuilder create(Header[] headers) {
        HeaderBuilder builder = new HeaderBuilder();
        builder.headers.setHeaders(headers);
        return builder;
    }

    public HeaderBuilder add(String key, String value) {
        headers.addHeader(new BasicHeader(key, value));
        return this;
    }

    public HeaderBuilder options() {
        return add("Origin", "*").add("Access-Control-Request-Method", "*").add("Access-Control-Request-Headers", "*");
    }

    public HeaderBuilder auth(String username, String password) {
        return add("Authorization", "Basic " + BASE_64.encodeToString((username + ":" + password).getBytes()));
    }

    public HeaderBuilder accept(ContentType... contentTypes) {
        if (contentTypes.length == 0) {
            return accept("*/*");
        }
        if (contentTypes.length == 1) {
            return accept(contentTypes[0].getMimeType());
        }
        List<String> list = new ArrayList<>();
        for (ContentType type : contentTypes) {
            list.add(type.getMimeType());
        }
        return add("Accept", StringUtils.join(list, ", "));
    }

    public HeaderBuilder accept(String types) {
        return add("Accept", types);
    }

    public HeaderBuilder acceptEncoding(String... encodings) {
        if (encodings.length == 0) {
            return this;
        } else {
            return add("Accept-Encoding", StringUtils.join(encodings, ", "));
        }
    }

    public HeaderBuilder acceptLanguage(String... languages) {
        if (languages.length == 0) {
            return this;
        } else {
            return add("Accept-Language", StringUtils.join(languages, ", "));
        }
    }

    public HeaderBuilder cookie(Map<String, String> kvs) {
        if (kvs.size() == 0) {
            return this;
        }
        List<String> cookies = new ArrayList<>(kvs.size());
        for (Map.Entry<String, String> entry : kvs.entrySet()) {
            cookies.add(entry.getKey() + "=" + entry.getValue());
        }
        return add("Cookie", StringUtils.join(cookies, "; "));
    }

    public HeaderBuilder cookie(String... kvs) {
        if (kvs.length == 0) {
            return this;
        }
        if (kvs.length % 2 == 1) {
            throw new RuntimeException("K-V number is odd.");
        } else {
            List<String> cookies = new ArrayList<>(kvs.length / 2);
            for (int i = 0; i < kvs.length / 2; i++) {
                cookies.add(kvs[2 * i] + "=" + kvs[2 * i + 1]);
            }
            return add("Cookie", StringUtils.join(cookies, "; "));
        }
    }

    public HeaderBuilder host(String host) {
        return add("Host", host);
    }

    public HeaderBuilder referer(String referer) {
        return add("Referer", referer);
    }

    public HeaderBuilder origin(String origin) {
        return add("Origin", origin);
    }

    public HeaderBuilder userAgent() {
        return userAgent(UA_CHROME);
    }

    public HeaderBuilder userAgent(String userAgent) {
        return add("User-Agent", userAgent);
    }

    public Header[] build() {
        return headers.getAllHeaders();
    }

    /**
     * 封装请求头
     */
    public static Header[] build(Map<String, String> headers) {
        List<Header> list = new ArrayList<>();
        // 封装请求头
        if (headers != null) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                // 设置到请求头到HttpRequestBase对象中
                list.add(new BasicHeader(entry.getKey(), entry.getValue()));
            }
        }
        return list.toArray(new Header[0]);
    }

}
